using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using Pavilion;
using System.Xml.Linq;

namespace Pavilion.GameTools
{
    public class TargetTool : GameToolBase
    {
        #region //////////////////////////////////////////////Attributes//////////////////////////////////////////////

        private bool ifMouseRight, ifMouseRightRec, ifCursorSwitch, ifReadyToAttack;
        private TargetTool.Alt targetAltitudeRec;
        private TargetTool.Alt mouseAltitude, characterAltitude;
        private PhysicalTypeTool physicalType;
        private MouseCursorTool mouseCursorTool;

        public event Action<TargetTool.Alt> MouseAltitudeChanged, CharacterAltitudeChanged;

        #endregion

        #region ////////////////////////////////////////////Initialization////////////////////////////////////////////

        public TargetTool(GameItem parentGameItem) : base(parentGameItem)
        {
            targetAltitudeRec = TargetTool.Alt.High;
        }

        #endregion

        #region ////////////////////////////////////////////////Methods///////////////////////////////////////////////

        public override void Load(XElement xmlProperties)
        {
            physicalType = ParentGameItem.ObtainTool<PhysicalTypeTool>();
            mouseCursorTool = ParentGameItem.ObtainTool<MouseCursorTool>();

            mouseCursorTool.MouseMoved += new Action<MouseCursor>(mouseCursor_MouseMoved);
            mouseCursorTool.LeftButtonPressed += new Action<MouseCursor>(mouseCursor_LeftButtonPressed);

            ParentGameItem.Disposed += (x) =>
            {
                physicalType = null;
                mouseCursorTool = null;
            };
        }

        public void EqualizeCursor()
        {
            physicalType.PolygonData.IsFlippedHorizontally = !getIfMouseRight();
        }

        private void TargetCalculation()
        {
            //Calculate the Altitude of the Target
            if (mouseCursorTool.Position.Y <= (int)physicalType.PolygonData.Position.Y - (55 * physicalType.PolygonData.Size))
                MouseAltitude = TargetTool.Alt.High;
            else if (mouseCursorTool.Position.Y > (int)physicalType.PolygonData.Position.Y - (55 * physicalType.PolygonData.Size) &&
                    mouseCursorTool.Position.Y < (int)physicalType.PolygonData.Position.Y + (55 * physicalType.PolygonData.Size))
                MouseAltitude = TargetTool.Alt.Mid;
            else
                MouseAltitude = TargetTool.Alt.Low;

            //Check if Mouse Position is at Left or Right side
            if (ifMouseRight)
            {
                if ((mouseCursorTool.Position.X <= (physicalType.PolygonData.Position.X - 25)))
                {
                    ifMouseRight = false;
                    ifCursorSwitch = true;
                }
                else
                    ifCursorSwitch = false;
            }
            else
            {
                if (mouseCursorTool.Position.X > (physicalType.PolygonData.Position.X + 25))
                {
                    ifMouseRight = true;
                    ifCursorSwitch = true;
                }
                else
                    ifCursorSwitch = false;
            }
        }

        #endregion

        #region ////////////////////////////////////////////Gets and Sets/////////////////////////////////////////////

        public TargetTool.Alt MouseAltitude
        {
            get { return mouseAltitude; }
            set
            {
                if (mouseAltitude == value)
                    return;

                mouseAltitude = value;
                OnMouseAltitudeChanged();
            }
        }

        public TargetTool.Alt CharacterAltitude
        {
            get { return characterAltitude; }
            set
            {
                if (characterAltitude == value)
                    return;

                characterAltitude = value;
                OnCharacterAltitudeChanged();
            }
        }

        public bool getIfReadyToAttack()
        {
            return ifReadyToAttack;
        }

        public void setIfReadyToAttack(bool ifReadyToAttack)
        {
            this.ifReadyToAttack = ifReadyToAttack;
        }

        public bool getIfMouseRight()
        {
            return ifMouseRight;
        }

        public bool getIfCursorSwitch()
        {
            return ifCursorSwitch;
        }

        #endregion

        #region ////////////////////////////////////////////////Events////////////////////////////////////////////////

        public void OnMouseAltitudeChanged()
        {
            if (MouseAltitudeChanged != null)
                MouseAltitudeChanged(MouseAltitude);
        }

        public void OnCharacterAltitudeChanged()
        {
            if (CharacterAltitudeChanged != null)
                CharacterAltitudeChanged(CharacterAltitude);
        }

        private void mouseCursor_MouseMoved(MouseCursor mouseCursor)
        {
            TargetCalculation();

            if (ifReadyToAttack)
            {
                //Checks whether mouse is out of the boundaries of the recorded attack
                if (ifMouseRight != ifMouseRightRec || MouseAltitude != targetAltitudeRec)
                    ifReadyToAttack = false;
            }
        }

        private void mouseCursor_LeftButtonPressed(MouseCursor mouseCursor)
        {
            //records the attack
            if (!ifReadyToAttack)
            {
                ifReadyToAttack = true;
                targetAltitudeRec = MouseAltitude;
                ifMouseRightRec = ifMouseRight;
            }
        }

        #endregion

        public enum Alt
        {
            High,
            Mid,
            Low
        }
    }
}
